home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 September / PCWorld_2008-09_cd.bin / v cisle / sadanastroju / lightning-0.8-tb-win.xpi / js / calWcapCalendar.js < prev    next >
Encoding:
JavaScript  |  2008-03-13  |  15.7 KB  |  439 lines

  1. /* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is Sun Microsystems code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * Sun Microsystems, Inc.
  19.  * Portions created by the Initial Developer are Copyright (C) 2007
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Daniel Boelzle <daniel.boelzle@sun.com>
  24.  *   Philipp Kewisch <mozilla@kewis.ch>
  25.  *
  26.  * Alternatively, the contents of this file may be used under the terms of
  27.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  28.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  29.  * in which case the provisions of the GPL or the LGPL are applicable instead
  30.  * of those above. If you wish to allow use of your version of this file only
  31.  * under the terms of either the GPL or the LGPL, and not to allow others to
  32.  * use your version of this file under the terms of the MPL, indicate your
  33.  * decision by deleting the provisions above and replace them with the notice
  34.  * and other provisions required by the GPL or the LGPL. If you do not delete
  35.  * the provisions above, a recipient may use your version of this file under
  36.  * the terms of any one of the MPL, the GPL or the LGPL.
  37.  *
  38.  * ***** END LICENSE BLOCK ***** */
  39.  
  40. function calWcapCalendar(/*optional*/session, /*optional*/calProps) {
  41.     this.initProviderBase();
  42.     this.m_session = session;
  43.     this.m_calProps = calProps;
  44. }
  45. calWcapCalendar.prototype = {
  46.     __proto__: calProviderBase.prototype,
  47.  
  48.     m_ifaces: [ calIWcapCalendar,
  49.                 calICalendar,
  50.                 Components.interfaces.calIChangeLog,
  51.                 Components.interfaces.calICalendarProvider,
  52.                 Components.interfaces.nsIInterfaceRequestor,
  53.                 Components.interfaces.nsIClassInfo,
  54.                 nsISupports ],
  55.  
  56.     // nsISupports:
  57.     QueryInterface: function calWcapCalendar_QueryInterface(iid) {
  58.         return doQueryInterface(this, calWcapCalendar.prototype, iid, this.m_ifaces, this);
  59.     },
  60.  
  61.     // nsIClassInfo:
  62.     getInterfaces: function calWcapCalendar_getInterfaces(count) {
  63.         count.value = this.m_ifaces.length;
  64.         return this.m_ifaces;
  65.     },
  66.     get classDescription() {
  67.         return calWcapCalendarModule.WcapCalendarInfo.classDescription;
  68.     },
  69.     get contractID() {
  70.         return calWcapCalendarModule.WcapCalendarInfo.contractID;
  71.     },
  72.     get classID() {
  73.         return calWcapCalendarModule.WcapCalendarInfo.classID;
  74.     },
  75.     getHelperForLanguage: function calWcapCalendar_getHelperForLanguage(language) { return null; },
  76.     implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
  77.     flags: 0,
  78.     
  79.     // nsIInterfaceRequestor:
  80.     getInterface: function calWcapCalendar_getInterface(iid, instance)
  81.     {
  82.         if (iid.equals(Components.interfaces.nsIAuthPrompt)) {
  83.             // use the window watcher service to get a nsIAuthPrompt impl
  84.             return getWindowWatcher().getNewAuthPrompter(null);
  85.         }
  86.         else if (iid.equals(Components.interfaces.nsIPrompt)) {
  87.             // use the window watcher service to get a nsIPrompt impl
  88.             return getWindowWatcher().getNewPrompter(null);
  89.         }
  90.         Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
  91.         return null;
  92.     },
  93.     
  94.     toString: function calWcapCalendar_toString() {
  95.         var str = this.session.toString();
  96.         if (this.m_calId)
  97.             str += (", calId=" + this.calId);
  98.         else
  99.             str += ", default calendar";
  100.         return str;
  101.     },
  102.     notifyError_: function calWcapCalendar_notifyError_(err, context, suppressOnError)
  103.     {
  104.         var msg;
  105.         var rc = getResultCode(err);
  106.         switch (rc) {
  107.         case calIErrors.OPERATION_CANCELLED:
  108.         case calIWcapErrors.WCAP_COMPONENT_NOT_FOUND:
  109.         case NS_ERROR_OFFLINE:
  110.             return;
  111.         default:
  112.             if (!checkErrorCode(rc, calIErrors.WCAP_ERROR_BASE, 8) &&
  113.                 (getErrorModule(rc) != NS_ERROR_MODULE_NETWORK)) {
  114.                 msg = logError(err, context);
  115.                 break;
  116.             }
  117.             // fallthru intended
  118.         case calIErrors.CAL_IS_READONLY:
  119.             // don't bloat the js error console with these errors, just log:
  120.             msg = errorToString(err);
  121.             log("error: " + msg, context);
  122.             break;
  123.         }
  124.         if (!suppressOnError) {
  125.             this.notifyObservers("onError",
  126.                                  err instanceof Components.interfaces.nsIException
  127.                                  ? [err.result, err.message] : [isNaN(err) ? -1 : err, msg]);
  128.         }
  129.     },
  130.     notifyError: function calWcapCalendar_notifyError(err, suppressOnError) {
  131.         this.notifyError_(err, this, suppressOnError);
  132.     },
  133.  
  134.     // calICalendarProvider:
  135.     get prefChromeOverlay() {
  136.         return null;
  137.     },
  138.     // displayName attribute already part of calIWcapCalendar
  139.     createCalendar: function calWcapCalendar_createCalendar(name, url, listener) {
  140.         throw NS_ERROR_NOT_IMPLEMENTED;
  141.     },
  142.     deleteCalendar: function calWcapCalendar_deleteCalendar(calendar, listener) {
  143.         throw NS_ERROR_NOT_IMPLEMENTED;
  144.     },
  145.     getCalendar: function calWcapCalendar_getCalendar(url) {
  146.         throw NS_ERROR_NOT_IMPLEMENTED;
  147.     },
  148.  
  149.     // calICalendar:
  150.     get name calWcapCalendar_nameGetter() {
  151.         var name = this.getProperty("name");
  152.         if (!name) {
  153.             name = this.displayName;
  154.         }
  155.         return name;
  156.     },
  157.     set name calWcapCalendar_nameSetter(aValue) {
  158.         return this.setProperty("name", aValue);
  159.     },
  160.  
  161.     get type() { return "wcap"; },
  162.  
  163.     m_uri: null,
  164.     get uri() {
  165.         return this.m_uri;
  166.     },
  167.     set uri(thatUri) {
  168.         this.m_uri = thatUri.clone();
  169.         var path = thatUri.path;
  170.         var qmPos = path.indexOf("?");
  171.         if (qmPos != -1) {
  172.             var pos = path.indexOf("?calid=", qmPos);
  173.             if (pos != -1) {
  174.                 var start = (pos + "?calid=".length);
  175.                 var end = path.indexOf("&", start);
  176.                 this.m_calId = decodeURIComponent(
  177.                     path.substring(start, end == -1 ? path.length : end));
  178.             }
  179.         }
  180.         return this.uri;
  181.     },
  182.  
  183.     getProperty: function calWcapCalendar_getProperty(aName) {
  184.         var value = this.__proto__.__proto__.getProperty.apply(this, arguments);
  185.         switch (aName) {
  186.         case "cache.supported":
  187.             value = false; // until bug 412914 and bug 412606 are fixed
  188.             break;
  189.         case "private.wcapCalendar":
  190.             value = this;
  191.             break;
  192.         case "readOnly":
  193.             if (value === null) {
  194.                 // tweak readOnly default to true for non-owned calendars:
  195.                 value = (this.m_session && this.session.isLoggedIn && !this.isOwnedCalendar);
  196.             }
  197.             break;
  198.         case "calendar-main-in-composite":
  199.             if (value === null && !this.isDefaultCalendar) {
  200.                 // tweak in-composite to false for secondary calendars:
  201.                 value = false;
  202.             }
  203.             break;
  204.         case "capabilities.alarms.popup.supported":
  205.             // CS cannot store X-props reliably (thus writing X-MOZ stamps etc is not possible).
  206.             // Popup alarms not available no matter what; wtf.
  207.             value = false;
  208.         }
  209.         return value;
  210.     },
  211.  
  212.     notifyObservers: function calWcapCalendar_notifyObservers(func, args) {
  213.         if (g_bShutdown) {
  214.             return;
  215.         }
  216.         this.observers.notify(func, args);
  217.     },
  218.  
  219.     // xxx todo: batch currently not used
  220.     startBatch: function calWcapCalendar_startBatch() {
  221.         this.notifyObservers("onStartBatch");
  222.     },
  223.     endBatch: function calWcapCalendar_endBatch() {
  224.         this.notifyObservers("onEndBatch");
  225.     },
  226.  
  227.     get sendItipInvitations() {
  228.         return false;
  229.     },
  230.  
  231.     get canRefresh() { return true; },
  232.     refresh: function calWcapCalendar_refresh() {
  233.         log("refresh.", this);
  234.         // invalidate cached results:
  235.         delete this.m_cachedResults;
  236.         // notify about refreshed calendar:
  237.         this.notifyObservers("onLoad", [this]);
  238.     },
  239.     
  240.     issueNetworkRequest: function calWcapCalendar_issueNetworkRequest(
  241.         request, respFunc, dataConvFunc, wcapCommand, params, accessRights)
  242.     {
  243.         var this_ = this;
  244.         // - bootstrap problem: no cal_props, no access check, no default calId
  245.         // - assure being logged in, thus the default cal_props are available
  246.         // - every subscribed calendar will come along with cal_props
  247.         return this.session.getSessionId(
  248.             request,
  249.             function getSessionId_resp(err, sessionId) {
  250.                 try {
  251.                     if (err)
  252.                         throw err;
  253.                     this_.assureAccess(accessRights);
  254.                     params += ("&calid=" + encodeURIComponent(this_.calId));
  255.                     this_.session.issueNetworkRequest(
  256.                         request, respFunc, dataConvFunc, wcapCommand, params);
  257.                 }
  258.                 catch (exc) {
  259.                     request.execSubRespFunc(respFunc, exc);
  260.                 }
  261.             });
  262.     },
  263.     
  264.     // calIWcapCalendar:
  265.     
  266.     m_session: null,
  267.     get session() {
  268.         if (!this.m_session) {
  269.             var uri = this.uri;
  270.             ASSERT(uri, "no URI set!");
  271.             var path = uri.path;
  272.             var qmPos = path.indexOf("?");
  273.             if (qmPos != -1) {
  274.                 uri = uri.clone();
  275.                 uri.path = path.substring(0, qmPos); // get rid of params
  276.             }
  277.             this.m_session = getWcapSessionFor(this, uri);
  278.         }
  279.         return this.m_session;
  280.     },
  281.  
  282.     m_calId: null,
  283.     get calId() {
  284.         if (this.m_calId)
  285.             return this.m_calId;
  286.         return this.session.defaultCalId;
  287.     },
  288.     
  289.     get ownerId() {
  290.         var ar = this.getCalProps("X-NSCP-CALPROPS-PRIMARY-OWNER");
  291.         if (ar.length == 0) {
  292.             var calId = this.calId;
  293.             log("cannot determine primary owner of calendar " + calId, this);
  294.             // fallback to calId prefix:
  295.             var nColon = calId.indexOf(":");
  296.             if (nColon >= 0)
  297.                 calId = calId.substring(0, nColon);
  298.             return calId;
  299.         }
  300.         return ar[0];
  301.     },
  302.     
  303.     get description() {
  304.         var ar = this.getCalProps("X-NSCP-CALPROPS-DESCRIPTION");
  305.         if (ar.length == 0) {
  306.             // fallback to display name:
  307.             return this.displayName;
  308.         }
  309.         return ar[0];
  310.     },
  311.     
  312.     get displayName() {
  313.         var ar = this.getCalProps("X-NSCP-CALPROPS-NAME");
  314.         if (ar.length == 0) {
  315.             // fallback to common name:
  316.             ar = this.getCalProps("X-S1CS-CALPROPS-COMMON-NAME");
  317.             if (ar.length == 0) {
  318.                 ar = [this.calId];
  319.             }
  320.         }
  321.         var name = ar[0];
  322.         var defaultCal = this.session.defaultCalendar;
  323.         if (defaultCal) {
  324.             var defName = (defaultCal.getProperty("account_name") ||
  325.                            defaultCal.getProperty("name"));
  326.             if (defName) {
  327.                 name += (" (" + defName + ")");
  328.             }
  329.         }
  330.         return name;
  331.     },
  332.     
  333.     get isOwnedCalendar() {
  334.         if (this.isDefaultCalendar)
  335.             return true; // default calendar is owned
  336.         return (this.ownerId == this.session.userId);
  337.     },
  338.     
  339.     get isDefaultCalendar() {
  340.         return !this.m_calId;
  341.     },
  342.     
  343.     getCalendarProperties: function calWcapCalendar_getCalendarProperties(propName, out_count) {
  344.         var ret = this.getCalProps(propName);
  345.         out_count.value = ret.length;
  346.         return ret;
  347.     },
  348.  
  349.     m_calProps: null,
  350.     getCalProps: function calWcapCalendar_getCalProps(propName) {
  351.         if (!this.m_calProps) {
  352.             log("soft error: no calprops, most possibly not logged in.", this);
  353. //             throw new Components.Exception("No calprops available!",
  354. //                                            Components.results.NS_ERROR_NOT_AVAILABLE);
  355.         }
  356.         return filterXmlNodes(propName, this.m_calProps);
  357.     },
  358.     
  359.     get defaultTimezone() {
  360.         var tzid = this.getCalProps("X-NSCP-CALPROPS-TZID");
  361.         if (tzid.length == 0) {
  362.             logError("defaultTimezone: cannot get X-NSCP-CALPROPS-TZID!", this);
  363.             return "UTC"; // fallback
  364.         }
  365.         return tzid[0];
  366.     },
  367.     
  368.     getAlignedTzid: function calWcapCalendar_getAlignedTzid(tz) {
  369.         var tzid = tz.tzid;
  370.         // check whether it is one cs supports:
  371.         if (!tz.isUTC && !tz.isFloating && !compareObjects(tz.provider, this.session)) {
  372.             log("not a server timezone: " + tzid);
  373.             var prefix = getTimezoneService().tzidPrefix;
  374.             if (tzid.indexOf(prefix) == 0) {
  375.                 // cut mozilla prefix: assuming that the latter string portion
  376.                 //                     semantically equals the demanded timezone
  377.                 tzid = tzid.substring(prefix.length);
  378.             }
  379.         }
  380.         if (!this.session.getTimezone(tzid)) {
  381.             // xxx todo: we could further on search for a matching region,
  382.             //           e.g. CET (in TZNAME), but for now stick to
  383.             //           user's default if not supported directly
  384.             var ret = this.defaultTimezone;
  385.             // use calendar's default:
  386.             log(tzid + " not supported, falling back to default: " + ret, this);
  387.             return ret;
  388.         }
  389.         return tzid;
  390.     },
  391.     
  392.     checkAccess: function calWcapCalendar_checkAccess(accessControlBits)
  393.     {
  394.         // xxx todo: take real acl into account
  395.         // for now, optimistically assuming that everybody has full access, server will check:
  396.         var granted = calIWcapCalendar.AC_FULL;
  397.         if (this.getProperty("readOnly")) {
  398.             granted &= ~(calIWcapCalendar.AC_COMP_WRITE |
  399.                          calIWcapCalendar.AC_PROP_WRITE);
  400.         }
  401.         // check whether every bit fits:
  402.         return ((accessControlBits & granted) == accessControlBits);
  403.     },
  404.     
  405.     assureAccess: function calWcapCalendar_assureAccess(accessControlBits)
  406.     {
  407.         if (!this.checkAccess(accessControlBits & (calIWcapCalendar.AC_COMP_WRITE |
  408.                                                    calIWcapCalendar.AC_PROP_WRITE))) {
  409.             // throw different error code for read-only:
  410.             throw new Components.Exception("Access denied!",
  411.                                            calIErrors.CAL_IS_READONLY);
  412.         }
  413.         if (!this.checkAccess(accessControlBits)) {
  414.             throw new Components.Exception("Access denied!",
  415.                                            calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR);
  416.             // xxx todo: throwing different error here, no
  417.             //           calIErrors.CAL_IS_READONLY anymore
  418.         }
  419.     },
  420.     
  421.     defineAccessControl: function calWcapCalendar_defineAccessControl(
  422.         userId, accessControlBits)
  423.     {
  424.         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  425.     },
  426.     
  427.     resetAccessControl: function calWcapCalendar_resetAccessControl(userId)
  428.     {
  429.         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  430.     },
  431.     
  432.     getAccessControlDefinitions: function calWcapCalendar_getAccessControlDefinitions(
  433.         out_count, out_users, out_accessControlBits)
  434.     {
  435.         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  436.     }
  437. };
  438.  
  439.